//
// Created by ascend on 2020/9/3.
//

#include <memory>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <string.h>
#include <cmath>
#include <regex>
#include "data_receiver.h"
#include "data_receiver_params.h"

using namespace std;

bool DataReceiver::IsInvalidIp(const string &ip) {
    regex re(kIpRegularExpression);
    smatch sm;
    return !regex_match(ip, sm, re);
}

bool DataReceiver::IsInvalidPort(const string &port) {
    if (port == "") {
        return true;
    }
    for (auto &c : port) {
        if (c >= '0' && c <= '9') {
            continue;
        } else {
            return true;
        }
    }
    int port_tmp = atoi(port.data());
    return (port_tmp < kPortMinNumber) || (port_tmp > kPortMaxNumber);
}

bool DataReceiver::IsInvalidAppName(const string &app_name) {
    regex re(kAppNameRegularExpression);
    smatch sm;
    return !regex_match(app_name, sm, re);
}


Result DataReceiver::Init() {
    PresenterServerParams register_param;
    register_param.app_id = "AIPainting";
    register_param.app_type = "display";
    register_param.host_ip = "192.168.1.223";
    register_param.port = 7008;
    PresenterChannels::GetInstance().Init(register_param);
    // create agent channel and register app
    ascend::presenter::Channel *agent_channel = PresenterChannels::GetInstance().GetChannel();
    if (agent_channel == nullptr) {
        INFO_LOG("register app failed.");
        return FAILED;
    }

    INFO_LOG("register app success.");

    return SUCCESS;
}

bool DataReceiver::DoReceiverProcess(void* objectDta, void* layoutData) {
    // get agent channel
    ascend::presenter::Channel *agent_channel = PresenterChannels::GetInstance().GetChannel();
    if (agent_channel == nullptr) {
        INFO_LOG("get agent channel to send failed.");
        return false;
    }

    // construct registered request Message and read message
    unique_ptr<google::protobuf::Message> data_rec;
    ascend::presenter::PresenterErrorCode agent_ret = agent_channel->ReceiveMessage(data_rec);
    if (agent_ret == ascend::presenter::PresenterErrorCode::kNone) {

        PaintingMessage::DataPackage *model_input_data_package = (PaintingMessage::DataPackage * )(data_rec.get());

        if(model_input_data_package == nullptr){
            INFO_LOG("receive data is null");
        }

        PaintingMessage::ModelInputData object_input = model_input_data_package->objectdata();
        std::string object_input_name = object_input.name();
        std::string object_input_data = object_input.data();
        INFO_LOG("object_input_name: %s", object_input_name.c_str());
        INFO_LOG("object_input_data size: %d", object_input_data.size());


        PaintingMessage::ModelInputData layout_input = model_input_data_package->layoutdata();
        std::string layout_input_name = layout_input.name();
        std::string layout_input_data = layout_input.data();
        INFO_LOG("layout_input_name: %s", layout_input_name.c_str());
        INFO_LOG("layout_input_data size: %d", layout_input_data.size());

        memcpy(objectDta, object_input_data.c_str(), object_input_data.size());
        memcpy(layoutData, layout_input_data.c_str(), layout_input_data.size());


    } else {
        INFO_LOG("sleep %d us", kSleepInterval);
        usleep(kSleepInterval);
    }

}

